use serde::{Deserialize, Serialize};
use sqlx::{FromRow, Type};
use sqlx::types::Json;
use crate::base::ServerError;
use crate::base::support_key::LKey;
use crate::db::get_conn;

#[derive(Debug, Serialize, Deserialize, Clone, Type)]
pub enum OperationType {
    /**
     * 键盘按下
     */
    #[serde(rename = "KeyDown")]
    KeyDown,
    /**
     * 键盘启动
     */
    #[serde(rename = "KeyUp")]
    KeyUp,
    /**
     * 鼠标移动到
     */
    #[serde(rename = "MouseTo")]
    MouseTo,
    /**
     * 鼠标左键点击
     */
    #[serde(rename = "MouseLeftClick")]
    MouseLeftClick,
    /**
     * 鼠标右键点击
     */
    #[serde(rename = "MouseRightClick")]
    MouseRightClick,
    /**
     * 鼠标右键点击
     */
    #[serde(rename = "DELAY")]
    DELAY,
}

#[derive(Debug, FromRow, Serialize)]
pub struct Operation {
    pub id: i32,
    pub operation_type: OperationType,
    pub step: u16,
    pub params: Json<OperationParam>,
    pub mark: Option<String>,
    pub group_id: i32,
}
#[derive(Debug, Deserialize)]
pub struct CreateOperation {
    pub operation_type: OperationType,
    pub step: u16,
    pub params: OperationParam,
    pub mark: Option<String>,
    pub group_id: i32,
}


#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct OperationParam {
    pub(crate) screenX: Option<i32>,
    pub(crate) screenY: Option<i32>,
    pub(crate) time: Option<u16>,
    pub(crate) key: Option<LKey>,
}

pub async fn list_operation(group_id:i32) -> Result<Vec<Operation>, ServerError> {
    let result = sqlx::query_as::<_, Operation>(r#"
    select * from tb_operation where group_id = ?
    "#)
        .bind(group_id)
        .fetch_all(&get_conn())
        .await?;
    Ok(result)
}
pub async fn delete_operations(id:i32) -> Result<bool, ServerError> {
    let res = sqlx::query(r#"
    delete from tb_operation where id = ?
    "#)
        .bind(id)
        .execute(&get_conn())
        .await?;
    Ok(res.rows_affected() > 0)
}

pub async fn add_operations(operation: CreateOperation) -> Result<bool, ServerError> {
    let res = sqlx::query(r#"
   insert into tb_operation (operation_type,step,params,mark,group_id) values (?, ?, ?, ?, ?)
    "#)
        .bind(operation.operation_type)
        .bind(operation.step)
        .bind(Json(operation.params))
        .bind(operation.mark)
        .bind(operation.group_id)
        .execute(&get_conn())
        .await?;
    Ok(res.rows_affected() > 0)
}